package com.bearox.trans.utils;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * @author Bearox
 */
@ApiModel(value = "响应结果")
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PUBLIC)
@Accessors(chain = true)
public class Result<T> {

    /**
     * 业务正常的时候code为0.
     */
    public static final String OK_CODE = "0";

    /**
     * 如果调用方没有设置错误码，那么错误码默认为-1.
     */
    public static final String GENERAL_ERROR_CODE = "-1";

    @ApiModelProperty(notes = "响应码，标识业务正确或者业务异常，0表示无异常", example = "0", required = true)
    private String c;

    @ApiModelProperty(notes = "错误信息，如果无异常则为空串", example = "success", required = true)
    private String m;

    @ApiModelProperty(notes = "业务数据")
    private T d;

    /**
     * @param data
     *            业务数据
     * @param <T>
     *            d数据的类型
     *
     * @return 封装好的表示业务成功的结构。
     */
    public static <T> Result<T> ok(final T data) {
        return new Result<>(OK_CODE, "", data);
    }

    /**
     * 没有业务数据的返回值。
     *
     * @return
     */
    public static <T> Result<T> ok() {
        return ok(null);
    }

    /**
     * @param code
     *            错误码
     * @param message
     *            错误信息
     *
     * @return
     */
    public static <T> Result<T> error(final String code, final String message) {
        return new Result<>(code, message, null);
    }

    public static <T> Result<T> error(final Exception e) {

        return new Result<>(e.getMessage(), e.getLocalizedMessage(), null);
    }

    /**
     * 默认错误码为{@link #GENERAL_ERROR_CODE}
     *
     * @param message
     *            错误信息
     *
     * @return
     */
    public static <T> Result<T> error(final String message) {
        return error(GENERAL_ERROR_CODE, message);
    }

    /**
     * 返回是否ok
     *
     * @return
     */
    public boolean success() {
        return OK_CODE.equals(this.d);
    }

    /**
     * 改成前端需要的list对象格式
     *
     * @param list
     * @return
     */
    public static Result<List<?>> toListObject(List<?> list) {
        return new Result<>(OK_CODE, null, list);
    }
}


